home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / dev / c / minigl.lha / MiniGL / src / aclip.c next >
Encoding:
C/C++ Source or Header  |  2002-04-17  |  9.8 KB  |  513 lines

  1. /*
  2.  * $Id: aclip.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $
  3.  *
  4.  * $Date: 2000/04/07 19:44:51 $
  5.  * $Revision: 1.1.1.1 $
  6.  *
  7.  * (C) 1999 by Hyperion
  8.  * All rights reserved
  9.  *
  10.  * This file is part of the MiniGL library project
  11.  * See the file Licence.txt for more details
  12.  *
  13.  */
  14.  
  15. static char rcsid[] = "$Id: aclip.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $";
  16.  
  17. #include "sysinc.h"
  18. #include "vertexarray.h"
  19. #include <math.h>
  20.  
  21.  
  22. #define LERP(t,a,b) \
  23.     ( (a) + (float)t * ( (b) - (a) ) )
  24.  
  25. #define CLIP_EPS (1e-7)
  26.  
  27. #define x1 (a->bx)
  28. #define y1 (a->by)
  29. #define z1 (a->bz)
  30. #define w1 (a->bw)
  31.  
  32. #define x2 (b->bx)
  33. #define y2 (b->by)
  34. #define z2 (b->bz)
  35. #define w2 (b->bw)
  36.  
  37.  
  38. static void A_ClipWZero(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading)
  39. {
  40.     float w;
  41.     ULONG outcode;
  42.     
  43.     float t = (CLIP_EPS-w1)/(w2-w1);
  44.  
  45.     if(shading == GL_SMOOTH)
  46.     {
  47.     r->v.color.a = LERP(t,a->v.color.a, b->v.color.a);
  48.     r->v.color.r = LERP(t,a->v.color.r, b->v.color.r);
  49.     r->v.color.g = LERP(t,a->v.color.g, b->v.color.g);
  50.     r->v.color.b = LERP(t,a->v.color.b, b->v.color.b);
  51.     }
  52.  
  53.     r->v.u = LERP(t,a->v.u, b->v.u);
  54.     r->v.v = LERP(t,a->v.v, b->v.v);
  55.  
  56.     r->bx = LERP(t,a->bx, b->bx);
  57.     r->by = LERP(t,a->by, b->by);
  58.     r->bz = LERP(t,a->bz, b->bz);
  59.     r->bw = CLIP_EPS;
  60.  
  61.     w = r->bw;
  62.     outcode = 0;
  63.  
  64.     if (-w > r->bx)
  65.     {
  66.         outcode |= MGL_CLIP_LEFT;
  67.     }
  68.     else if (r->bx > w)
  69.     {
  70.         outcode |= MGL_CLIP_RIGHT;
  71.     }
  72.  
  73.     if (-w > r->by)
  74.     {
  75.         outcode |= MGL_CLIP_BOTTOM;
  76.     }
  77.     else if (r->by > w)
  78.     {
  79.         outcode |= MGL_CLIP_TOP;
  80.     }
  81.  
  82.     if (-w > r->bz)
  83.     {
  84.         outcode |= MGL_CLIP_BACK;
  85.     }
  86.     else if (r->bz > w)
  87.     {
  88.         outcode |= MGL_CLIP_FRONT;
  89.     }
  90.  
  91.     r->outcode = outcode;
  92. }
  93.  
  94. static void A_ClipTop(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading)
  95. {
  96.     float w;
  97.     ULONG outcode;
  98.  
  99.     float t = (w1-y1)/((w1-y1)-(w2-y2));
  100.  
  101.     if(shading == GL_SMOOTH)
  102.     {
  103.     r->v.color.a = LERP(t,a->v.color.a, b->v.color.a);
  104.     r->v.color.r = LERP(t,a->v.color.r, b->v.color.r);
  105.     r->v.color.g = LERP(t,a->v.color.g, b->v.color.g);
  106.     r->v.color.b = LERP(t,a->v.color.b, b->v.color.b);
  107.     }
  108.  
  109.     r->v.u = LERP(t,a->v.u, b->v.u);
  110.     r->v.v = LERP(t,a->v.v, b->v.v);
  111.  
  112.     r->bx = LERP(t,a->bx, b->bx);
  113.     r->bz = LERP(t,a->bz, b->bz);
  114.     r->bw = LERP(t,a->bw, b->bw);
  115.     r->by = r->bw;
  116.  
  117. /*
  118. Surgeon: this is always the 2nd last routine called, so here is no need to recode since a top-code means that there can be no bottom-code - we can safely set the outcode of the clipped vert to 0
  119. */
  120.  
  121. #if 1
  122.     r->outcode = 0;
  123. #else
  124.  
  125.     w = r->bw;
  126.     outcode = 0;
  127.  
  128.     if (r->bw < CLIP_EPS )
  129.     {
  130.         outcode |= MGL_CLIP_NEGW;
  131.     }
  132.  
  133.     if (-w > r->bx)
  134.     {
  135.         outcode |= MGL_CLIP_LEFT;
  136.     }
  137.     else if (r->bx > w)
  138.     {
  139.         outcode |= MGL_CLIP_RIGHT;
  140.     }
  141.  
  142.     if (-w > r->bz)
  143.     {
  144.         outcode |= MGL_CLIP_BACK;
  145.     }
  146.     else if (r->bz > w)
  147.     {
  148.         outcode |= MGL_CLIP_FRONT;
  149.     }
  150.  
  151.     r->outcode = outcode;
  152. #endif
  153. }
  154.  
  155. static void A_ClipBottom(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading)
  156. {
  157.     float w;
  158.     ULONG outcode;
  159.  
  160.     float t = (w1+y1)/((w1+y1)-(w2+y2));
  161.  
  162.     if(shading == GL_SMOOTH)
  163.     {
  164.     r->v.color.a = LERP(t,a->v.color.a, b->v.color.a);
  165.     r->v.color.r = LERP(t,a->v.color.r, b->v.color.r);
  166.     r->v.color.g = LERP(t,a->v.color.g, b->v.color.g);
  167.     r->v.color.b = LERP(t,a->v.color.b, b->v.color.b);
  168.     }
  169.  
  170.     r->v.u = LERP(t,a->v.u, b->v.u);
  171.     r->v.v = LERP(t,a->v.v, b->v.v);
  172.  
  173.     r->bx = LERP(t,a->bx, b->bx);
  174.     r->bz = LERP(t,a->bz, b->bz);
  175.     r->bw = LERP(t,a->bw, b->bw);
  176.     r->by = -r->bw;
  177.  
  178. /*
  179. Surgeon: this is always the last routine called, so here is no need to recode - we can safely set the outcode of the clipped vert to 0
  180. */
  181.  
  182. #if 1
  183.     r->outcode = 0;
  184. #else
  185.     w = r->bw;
  186.     outcode = 0;
  187.  
  188.     if (r->bw < CLIP_EPS )
  189.     {
  190.         outcode |= MGL_CLIP_NEGW;
  191.     }
  192.  
  193.     if (-w > r->bx)
  194.     {
  195.         outcode |= MGL_CLIP_LEFT;
  196.     }
  197.     else if (r->bx > w)
  198.     {
  199.         outcode |= MGL_CLIP_RIGHT;
  200.     }
  201.  
  202.     if (-w > r->bz)
  203.     {
  204.         outcode |= MGL_CLIP_BACK;
  205.     }
  206.     else if (r->bz > w)
  207.     {
  208.         outcode |= MGL_CLIP_FRONT;
  209.     }
  210.  
  211.     r->outcode = outcode;
  212. #endif
  213. }
  214.  
  215. static void A_ClipLeft(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading)
  216. {
  217.     float w;
  218.     ULONG outcode;
  219.  
  220.     float t = (w1+x1)/((w1+x1)-(w2+x2));
  221.  
  222.     if(shading == GL_SMOOTH)
  223.     {
  224.     r->v.color.a = LERP(t,a->v.color.a, b->v.color.a);
  225.     r->v.color.r = LERP(t,a->v.color.r, b->v.color.r);
  226.     r->v.color.g = LERP(t,a->v.color.g, b->v.color.g);
  227.     r->v.color.b = LERP(t,a->v.color.b, b->v.color.b);
  228.     }
  229.  
  230.     r->v.u = LERP(t,a->v.u, b->v.u);
  231.     r->v.v = LERP(t,a->v.v, b->v.v);
  232.  
  233.     r->by = LERP(t,a->by, b->by);
  234.     r->bz = LERP(t,a->bz, b->bz);
  235.     r->bw = LERP(t,a->bw, b->bw);
  236.     r->bx = -r->bw;
  237.  
  238.     w = r->bw;
  239.     outcode = 0;
  240.  
  241. /*
  242.     if (r->bw < CLIP_EPS )
  243.     {
  244.         outcode |= MGL_CLIP_NEGW;
  245.     }
  246. */
  247.  
  248.     if (-w > r->by)
  249.     {
  250.         outcode |= MGL_CLIP_BOTTOM;
  251.     }
  252.     else if (r->by > w)
  253.     {
  254.         outcode |= MGL_CLIP_TOP;
  255.     }
  256.  
  257.     if (-w > r->bz)
  258.     {
  259.         outcode |= MGL_CLIP_BACK;
  260.     }
  261.     else if (r->bz > w)
  262.     {
  263.         outcode |= MGL_CLIP_FRONT;
  264.     }
  265.  
  266.     r->outcode = outcode;
  267. }
  268.  
  269. static void A_ClipRight(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading)
  270. {
  271.     float w;
  272.     ULONG outcode;
  273.  
  274.     float t = (w1-x1)/((w1-x1)-(w2-x2));
  275.  
  276.     if(shading == GL_SMOOTH)
  277.     {
  278.     r->v.color.a = LERP(t,a->v.color.a, b->v.color.a);
  279.     r->v.color.r = LERP(t,a->v.color.r, b->v.color.r);
  280.     r->v.color.g = LERP(t,a->v.color.g, b->v.color.g);
  281.     r->v.color.b = LERP(t,a->v.color.b, b->v.color.b);
  282.     }
  283.  
  284.     r->v.u = LERP(t,a->v.u, b->v.u);
  285.     r->v.v = LERP(t,a->v.v, b->v.v);
  286.  
  287.     r->by = LERP(t,a->by, b->by);
  288.     r->bz = LERP(t,a->bz, b->bz);
  289.     r->bw = LERP(t,a->bw, b->bw);
  290.     r->bx = r->bw;
  291.  
  292.     w = r->bw;
  293.     outcode = 0;
  294.  
  295. /*
  296.     if (r->bw < CLIP_EPS )
  297.     {
  298.         outcode |= MGL_CLIP_NEGW;
  299.     }
  300. */
  301.  
  302.     if (-w > r->by)
  303.     {
  304.         outcode |= MGL_CLIP_BOTTOM;
  305.     }
  306.     else if (r->by > w)
  307.     {
  308.         outcode |= MGL_CLIP_TOP;
  309.     }
  310.  
  311.     if (-w > r->bz)
  312.     {
  313.         outcode |= MGL_CLIP_BACK;
  314.     }
  315.     else if (r->bz > w)
  316.     {
  317.         outcode |= MGL_CLIP_FRONT;
  318.     }
  319.  
  320.     r->outcode = outcode;
  321. }
  322.  
  323. static void A_ClipFront(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading)
  324. {
  325.     float w;
  326.     ULONG outcode;
  327.  
  328.     float t = (w1-z1)/((w1-z1)-(w2-z2));
  329.  
  330.     if(shading == GL_SMOOTH)
  331.     {
  332.     r->v.color.a = LERP(t,a->v.color.a, b->v.color.a);
  333.     r->v.color.r = LERP(t,a->v.color.r, b->v.color.r);
  334.     r->v.color.g = LERP(t,a->v.color.g, b->v.color.g);
  335.     r->v.color.b = LERP(t,a->v.color.b, b->v.color.b);
  336.     }
  337.  
  338.     r->v.u = LERP(t,a->v.u, b->v.u);
  339.     r->v.v = LERP(t,a->v.v, b->v.v);
  340.  
  341.     r->bx = LERP(t,a->bx, b->bx);
  342.     r->by = LERP(t,a->by, b->by);
  343.     r->bw = LERP(t,a->bw, b->bw);
  344.     r->bz = r->bw;
  345.  
  346.     w = r->bw;
  347.     outcode = 0;
  348.  
  349. /*
  350.     if (r->bw < CLIP_EPS )
  351.     {
  352.         outcode |= MGL_CLIP_NEGW;
  353.     }
  354.  
  355.     if (-w > r->bx)
  356.     {
  357.         outcode |= MGL_CLIP_LEFT;
  358.     }
  359.     else if (r->bx > w)
  360.     {
  361.         outcode |= MGL_CLIP_RIGHT;
  362.     }
  363. */
  364.     if (-w > r->by)
  365.     {
  366.         outcode |= MGL_CLIP_BOTTOM;
  367.     }
  368.     else if (r->by > w)
  369.     {
  370.         outcode |= MGL_CLIP_TOP;
  371.     }
  372.  
  373.     r->outcode = outcode;
  374. }
  375.  
  376. static void A_ClipBack(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading)
  377. {
  378.     float w;
  379.     ULONG outcode;
  380.  
  381.     float t = (w1+z1)/((w1+z1)-(w2+z2));
  382.  
  383.     if(shading == GL_SMOOTH)
  384.     {
  385.     r->v.color.a = LERP(t,a->v.color.a, b->v.color.a);
  386.     r->v.color.r = LERP(t,a->v.color.r, b->v.color.r);
  387.     r->v.color.g = LERP(t,a->v.color.g, b->v.color.g);
  388.     r->v.color.b = LERP(t,a->v.color.b, b->v.color.b);
  389.     }
  390.  
  391.     r->v.u = LERP(t,a->v.u, b->v.u);
  392.     r->v.v = LERP(t,a->v.v, b->v.v);
  393.  
  394.     r->bx = LERP(t,a->bx, b->bx);
  395.     r->by = LERP(t,a->by, b->by);
  396.     r->bw = LERP(t,a->bw, b->bw);
  397.     r->bz = -r->bw;
  398.  
  399.     w = r->bw;
  400.     outcode = 0;
  401.  
  402. /*
  403.     if (r->bw < CLIP_EPS )
  404.     {
  405.         outcode |= MGL_CLIP_NEGW;
  406.     }
  407.  
  408.     if (-w > r->bx)
  409.     {
  410.         outcode |= MGL_CLIP_LEFT;
  411.     }
  412.     else if (r->bx > w)
  413.     {
  414.         outcode |= MGL_CLIP_RIGHT;
  415.     }
  416. */
  417.     if (-w > r->by)
  418.     {
  419.         outcode |= MGL_CLIP_BOTTOM;
  420.     }
  421.     else if (r->by > w)
  422.     {
  423.         outcode |= MGL_CLIP_TOP;
  424.     }
  425.  
  426.     r->outcode = outcode;
  427. }
  428.  
  429.  
  430. #undef x1
  431. #undef y1
  432. #undef z1
  433. #undef w1
  434. #undef x2
  435. #undef y2
  436. #undef z2
  437. #undef w2
  438.  
  439.  
  440. /*
  441. ** Complicated clipping macro stuff.
  442. */
  443.  
  444. #define VERTP(i) &(context->VertexBuffer[a->verts[i]])
  445. #define VERT(i)  (context->VertexBuffer[a->verts[i]])
  446. #define POLYSWAP \
  447.     if (b->numverts == 0){out->numverts = 0; return;} \
  448.     temp=a; a=b; b=temp; \
  449.  
  450. #define DOCLIP(edge, routine)                                           \
  451.     if (or_codes & edge)                                                 \
  452.     {                                                                     \
  453.         b->numverts = 0;                                                   \
  454.         prev = a->numverts-1;                                               \
  455.     i=0; do    {                                                                          \
  456.             /* Case 1 and 4*/                                                  \
  457.             if (!(VERT(prev).outcode & edge))                                   \
  458.             {                                                                    \
  459.                 b->verts[b->numverts] = a->verts[prev];                           \
  460.                 b->numverts++;                                                     \
  461.             }                                                                       \
  462.             /* Case 3 and 4 */                                                       \
  463.             if ((VERT(prev).outcode ^ VERT(i).outcode) & edge)                        \
  464.             {                                                                                  \
  465.                 A_##routine (VERTP(prev), VERTP(i), &(context->VertexBuffer[free]), (const GLenum)context->ShadeModel);                \
  466.                 b->verts[b->numverts]=free++;                                              \
  467.                 b->numverts++;                                                             \
  468.             }                     \
  469.             prev = i;             \
  470.         }  while (++i < a->numverts); \
  471.         POLYSWAP                      \
  472.     }                          
  473.  
  474.  
  475.  
  476. void AE_ClipPoly(GLcontext context, PolyBuffer *out, int clipstart, ULONG or_codes)
  477. {
  478.     PolyBuffer output;
  479.     PolyBuffer *a, *b, *temp;
  480.     int i,j;
  481.     int prev;
  482.     int free = clipstart;
  483.  
  484.     a = out; b=&output;
  485.  
  486.     DOCLIP(MGL_CLIP_NEGW, ClipWZero);
  487.  
  488.     j = 0;
  489.     do
  490.     {
  491.         or_codes |= context->VertexBuffer[a->verts[j]].outcode;
  492.     j++;
  493.     } while (j < a->numverts);
  494.  
  495.     DOCLIP(MGL_CLIP_LEFT, ClipLeft)
  496.     DOCLIP(MGL_CLIP_RIGHT, ClipRight)
  497.     DOCLIP(MGL_CLIP_FRONT, ClipFront)
  498.     DOCLIP(MGL_CLIP_BACK, ClipBack)
  499.     DOCLIP(MGL_CLIP_TOP, ClipTop)
  500.     DOCLIP(MGL_CLIP_BOTTOM, ClipBottom)
  501.  
  502.     out->nextfree = free;
  503.     out->numverts = a->numverts;
  504.  
  505.     j = 0;
  506.     do
  507.     {
  508.        out->verts[j] = a->verts[j];
  509.     j++;
  510.     } while (j < a->numverts);
  511.  
  512. }
  513.